﻿using BaseUi.Models;
using Common.Device.Models;
using Common.Device.ViewModels;
using EnumsNET;
using LiveCharts;
using NPOI.POIFS.Crypt;
using Ping9719.WpfEx;
using Ping9719.WpfEx.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Input;

namespace BaseUi.ViewModel
{
    public class HomeViewModel : BindableBase
    {
        private Db.MesDb Mesdb = new Db.MesDb();
        public Action focusInput;
        CancellationTokenSource cancellationToken = null;//停止
        ManualResetEvent manualReset = null;//暂停、继续
        WarnInfoContainer WarnInfo = new WarnInfoContainer();//警告、错误等信息
        /// <summary>
        /// 测试表
        /// </summary>
        public List<TestListViewModel> test1List;
        public string mocode;
        private string code;
        public string Code { get => code; set { SetProperty(ref code, value); } }
        private string nocode;
        public string Nocode { get => nocode; set { SetProperty(ref nocode, value); } }
        private string pro;
        public string Pro { get => pro; set { SetProperty(ref pro, value); } }
        private bool canScan = true;
        public bool CanScan { get => canScan; set { SetProperty(ref canScan, value); } }

        #region 绑定
        private string textErr;
        /// <summary>
        /// 错误文本
        /// </summary>
        public string TextErr { get => textErr; set { SetProperty(ref textErr, value); } }
        public ICommand ClearTextInfoCommand { get => new DelegateCommand(ClearTextInfo); }
        /// <summary>
        /// 清除信息文本
        /// </summary>
        public void ClearTextInfo()
        {
            TextBoxLog.ClearLog();
        }
        public ICommand ClearTextErrCommand { get => new DelegateCommand(ClearTextErr); }
        /// <summary>
        /// 清除全部错误文本
        /// </summary>
        public void ClearTextErr()
        {
            WarnInfo.RemoveAll(WarnInfoType.AlwayWarn);
        }
        #endregion

        #region 页面加载时任务
        /// <summary>
        /// 页面第一次加载时执行的任务
        /// </summary>
        public void LoadTask()
        {
            //注册警告事件
            WarnInfo.WarnInfoChanged += (all, add, rem) =>
            {
                //界面展示
                TextErr = string.Join(Environment.NewLine, all.OrderBy(o => (o.WarnType, o.Source, o.Text)));
                //日志记录
                Logs.Write(add.Concat(rem).Select(o => o.ToString()), LogsType.Warning);
                //数据库保存
                if (WarnInfoDb.IsEnabled)
                {
                    WarnInfoDb.db.Insertable(WarnInfoItemDb.GetList(add)).ExecuteCommand();
                    WarnInfoDb.db.Updateable(WarnInfoItemDb.GetList(rem)).ExecuteCommand();
                }
            };

            Task.Run(PlcErrListen);
        }

        /// <summary>
        /// 根据Excel里面的内容监听plc错误信息
        /// </summary>
        async void PlcErrListen()
        {
            //Excel解析的错误格式
            var excelErrAll = ExcelDeviceAlarmModel.GetDatas(LocalFile.PlcDotPath);
            while (true)
            {
                //需要将null替换为设备，如“LocalStatic.Plc”，并去里面解开注释
                var excelErr = ExcelDeviceAlarmModel.ReadPlcAlarm(excelErrAll, LocalStatic.Plc);

                WarnInfo.AddOrUpdate(excelErr.Select(o => new WarnInfoItem()
                {
                    Text = o.名称,
                    WarnType = WarnInfoType.WhileWarn,
                    Level = o.级别,
                    Solution = o.解决方式,
                    Source = "PLC"
                }), "PLC");

                await Task.Delay(500);
            }
        }
        #endregion

        #region 业务

        private RunState runState = RunState.Stop;
        /// <summary>
        /// 运行状态
        /// </summary>
        public RunState RunState { get => runState; set { SetProperty(ref runState, value); } }

        public ICommand RunStateClickCommand { get => new DelegateCommand<RunStateButtonClick>(RunStateClick); }
        /// <summary>
        /// 运行状态
        /// </summary>
        public void RunStateClick(RunStateButtonClick clickrunState)
        {
            //if (Nocode==""||Nocode==null)
            //{
            //    TextBoxLog.AddLog("未填写指令号");
            //    return;
            //}
            if (clickrunState == RunStateButtonClick.Start)
            {
                //if (mocode!=Nocode)
                //{
                //    TextBoxLog.AddLog("指令号更改未确认");
                //    return;
                //}
                TextBoxLog.AddLog("点击开始");
                Start();
            }
            else if (clickrunState == RunStateButtonClick.Pause)
            {
                TextBoxLog.AddLog("点击暂停");
                Pause();
            }
            else if (clickrunState == RunStateButtonClick.Continue)
            {
                //if (mocode!=Nocode)
                //{
                //    TextBoxLog.AddLog("指令号更改未确认");
                //    return;
                //}
                TextBoxLog.AddLog("点击继续");
                Continue();
            }
            else if (clickrunState == RunStateButtonClick.Stop)
            {
                TextBoxLog.AddLog("点击停止");
                Stop();
            }
            else if (clickrunState == RunStateButtonClick.Rset)
            {

            }
        }

        /// <summary>
        /// 开始
        /// </summary>
        public void Start()
        {
            cancellationToken = new CancellationTokenSource();
            manualReset = new ManualResetEvent(true);
            Task.Run(TaskAll);
            RunState = RunState.Run;
        }

        /// <summary>
        /// 暂停
        /// </summary>
        public void Pause()
        {
            manualReset.Reset();
            RunState = RunState.Pause;
        }

        /// <summary>
        /// 继续
        /// </summary>
        public void Continue()
        {
            manualReset.Set();
            RunState = RunState.Run;
        }

        /// <summary>
        /// 停止
        /// </summary>
        public void Stop()
        {
            cancellationToken.Cancel();
            RunState = RunState.Stop;
        }

        private void TaskAll()
        {

            try
            {
                Task.WaitAll(Task1());
            }
            catch (Exception ex)
            {
                TextBoxLog.AddLog($"错误：{ex.ToString()}");
            }
            finally
            {
                Stop();
                TextBoxLog.AddLog("已停止：全部");
            }
        }

        private async Task Task1()
        {
            try
            {
                while (true)
                {
                    await Task.Delay(1000);
                    //监听：开始、暂停、停止
                    While.Wait(cancellationToken.Token, manualReset);
                    if (test1List?.Count != 0)
                    {
                        CanScan = false;
                        foreach (var item in test1List)
                        {
                            string retul = "";
                            //string retul1 = getsn(mocode);
                            //if (retul=="-2")
                            //{
                            //    TextBoxLog.AddLog("已停止1");
                            //    return;
                            //}
                            var dt = DateTime.Now;
                            
                            TextBoxLog.AddLog($"{item.num}开始测试");
                            var re = item.Start(Code, cancellationToken, manualReset);
                            while (item.State==Common.Device.Enums.TestEnum.TestState.测试)
                            {
                                While.Wait(cancellationToken.Token, manualReset);
                                Thread.Sleep(100);
                                //急停或光栅信号
                                //if (false)
                                //{
                                //    item.Stop().Wait();
                                //    cancellationToken?.Cancel();
                                //}
                            }
                            
                            //测试完成的mes字典，按需上传
                            var mes = new Dictionary<string, DeviceResult>();
                            DeviceResult value1 = new DeviceResult();
                            DeviceResult value2 = new DeviceResult();
                            DeviceResult value3 = new DeviceResult();
                            DeviceResult value4 = new DeviceResult();
                            string mesretul = "";
                            foreach (var order in item.Orders)
                            {
                                string ordername = order.name;
                                foreach (var testOrder in order.orders)
                                {
                                    if (!string.IsNullOrEmpty(testOrder.mes))
                                    {
                                        mes.Add(testOrder.mes, testOrder.result);
                                    }
                                    if (!testOrder.result.success&&testOrder.result.result is not null)
                                    {
                                        mesretul=mesretul+$"{ordername}结果：{testOrder.result.result}";
                                    }
                                }
                            }
                            TextBoxLog.AddLog(mesretul);

                            TextBoxLog.AddLog($"{item.num}{item.State.ToString()}");
                            string sntext = "";
                            string sn = "";
                            //string code = "";
                            string btmac = "";
                            string btname = "";
                            string rev = "";
                            string number = "";
                            ZhiKongInfos one = new ZhiKongInfos()
                            {
                                SN = "",
                                Code = "",
                                BT_MAC = "",
                                CPU = "",
                                BT_NAME = "",
                                Station = LocalFile.Config.GetStation,
                                TestOS_Rev = "",
                                State = "",
                                restul = "",
                                Time =  dt,
                            };

                            if (mes.TryGetValue("cx", out value1))
                            {
                                if (!mes.TryGetValue("bt", out value2))
                                {
                                    TextBoxLog.AddLog("蓝牙测试没有字段bt");
                                    break;
                                }
                                if (!mes.TryGetValue("cpu", out value3))
                                {
                                    TextBoxLog.AddLog("cpu获取没有字段cpu");
                                    break;
                                }
                                if (!mes.TryGetValue("sc", out value4))
                                {
                                    TextBoxLog.AddLog("上传没有字段上传");
                                    break;
                                }
                                if (LocalFile.Config.WorkStation=="初测")
                                {
                                    if (!value4.result.Contains("初次上传"))
                                    {
                                        TextBoxLog.AddLog("复测测试表与初测工序异常");
                                        break;
                                    }
                                }
                                if (LocalFile.Config.WorkStation=="复测")
                                {
                                    if (value4.result.Contains("初次上传"))
                                    {
                                        TextBoxLog.AddLog("初次测试表与复测工序异常");
                                        break;
                                    }
                                }
                                if (value2.result is null)
                                {
                                    value2.result="";
                                }
                                if (value3.result is null)
                                {
                                    value3.result="";
                                }
                                if (!value1.success)
                                {
                                    one.SN = value1.value.ToString();
                                    one.restul = value1.result;
                                    one.Code = "";
                                    one.State = item.State.ToString();
                                    one.restul = mesretul;
                                    one.TestOS_Rev="";
                                    one.Time = dt;
                                }
                                else
                                {
                                    sntext = value1.result;
                                    string[] parts = sntext.Split(';');
                                    //if (value4.result.Contains("初次上传"))
                                    //{
                                    //    sn = parts[0];
                                    //    rev = parts[1];
                                    //    btname = parts[2];
                                    //}
                                    if (parts.Length==3)
                                    {
                                        sn = parts[0];
                                        rev = parts[1];
                                        btname = parts[2];
                                    }
                                    else
                                    {
                                        sn = parts[4];
                                        rev = parts[3];
                                        btname = parts[1];
                                    }
                                    Nocode = sn.Substring(0, 14);
                                    one.SN = sn;
                                    one.restul = mesretul;
                                    one.Code = sn.Substring(0, 14);
                                    one.BT_NAME = btname;
                                    one.BT_MAC = value2.result;
                                    one.CPU = value3.result;
                                    one.State =value1.result+item.State.ToString();
                                    one.restul = "";
                                    one.TestOS_Rev=rev;
                                    one.Time = dt;
                                    one.Station = LocalFile.Config.GetStation;
                                    var gfetlist = Mesdb.db.Queryable<ZhiKongInfo>().Where(o => o.SN == sn &&o.BT_NAME==btname).ToList();
                                    var data = gfetlist[0];
                                    if (value4.success)
                                    {
                                        //data.BT_MAC = value2.result;
                                        //data.CPU=value3.result;
                                        //data.Time = dt;
                                        //data.Station=LocalFile.Config.GetStation;
                                        //将测试成功的写入过站表
                                        if (value4.result.Contains("初次上传"))
                                        {
                                            data.BT_MAC = value2.result;
                                            data.CPU=value3.result;
                                            data.restul = mesretul;
                                            data.State=item.State.ToString();
                                            data.Time = dt;
                                            data.Station=LocalFile.Config.GetStation;
                                            Mesdb.db.Updateable(data).ExecuteCommand();
                                        }
                                        else
                                        {
                                            data.restul1 = mesretul;
                                            data.State1=item.State.ToString();
                                            data.Time1 = dt;
                                            data.Station1=LocalFile.Config.GetStation;
                                            Mesdb.db.Updateable(data).ExecuteCommand();
                                        }
                                    }
                                    if (data.State1 is null)
                                    {
                                        data.State1="";
                                    }
                                    if (data.restul1 is null)
                                    {
                                        data.restul1="";
                                    }
                                    if (data.Station is null)
                                    {
                                        data.Station=LocalFile.Config.GetStation;
                                    }
                                    if (data.Station1 is null)
                                    {
                                        data.Station1=LocalFile.Config.GetStation;
                                    }
                                    if (data.PackageWorker is null)
                                    {
                                        data.PackageWorker="";
                                    }
                                    if (data.PackageTime is null)
                                    {
                                        data.PackageTime=dt;
                                    }
                                    if (data.Time1 == null)
                                    {
                                        data.Time1=dt;
                                    }

                                    DataDb.dbBox.Insertable(data).ExecuteCommand();
                                }
                            }
                            
                            //将测试过的写入测试记录表（无论成功失败）
                            DataDb.dbBoxs.Insertable(one).ExecuteCommand();
                            Mesdb.db.Insertable(one).ExecuteCommand();
                        }
                        break;
                    }
                }
            }
            catch (OperationCanceledException)
            {
                if (test1List?.Count != 0)
                {
                    foreach (var item in test1List)
                    {
                        item.Stop().Wait();
                    }
                }
                Code = "";
                TextBoxLog.AddLog("已停止1");
            }
            catch (Exception ex)
            {
                TextBoxLog.AddLog($"错误：{ex.ToString()}");
            }
            finally
            {
                if (Nocode!="")
                {
                    OutputStatChartView.viewModel.UpdataData(Nocode);
                }
                cancellationToken?.Cancel();
                CanScan = true;
                focusInput?.Invoke();
            }
        }

        private string getsn(string mocode)
        {
            try
            {
                int luisui = Mesdb.db.Queryable<ZhiKongInfo>().Where(o => o.Code == mocode &&o.State=="通过").Count();

                return mocode+(luisui + 1).ToString().PadLeft(5, '0');
            }
            catch (Exception ee)
            {
                TextBoxLog.AddLog($"查询流水号错误：{ee.ToString()}");
                return "-2";
            }
        }
        #endregion
    }
}
